package com.youlai.system.security.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONArray;
import cn.hutool.jwt.JWTPayload;
import com.youlai.system.model.entity.Employ;
import com.youlai.system.security.constant.JwtClaimConstants;
import com.youlai.system.security.model.SysUserDetails;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

public class JwtUtil {
    /**
     * 生成jwt
     * 使用Hs256算法, 私匙使用固定秘钥
     *
     * @param secretKey jwt秘钥
     * @param ttlMillis jwt过期时间(毫秒)
     * @param claims    设置的信息
     * @return
     */
    public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // 指定签名的时候使用的签名算法，也就是header那部分
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);

        // 生成一个随机的 UUID 作为 JWT ID（JTI）
        String jti = UUID.randomUUID().toString();



        claims.put("角色集合",claims.get("角色集合"));


        // 设置jwt的body
        JwtBuilder builder = Jwts.builder()
                // 如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
                .setClaims(claims)
                // 设置 JWT ID（JTI）
                .setId(jti)
                // 设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
                // 设置过期时间
                .setExpiration(exp);

        return builder.compact();
    }

    /**
     * Token解密
     *
     * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
     * @param token     加密后的token
     * @return
     */
    public static Claims parseJWT(String secretKey, String token) {
        try {
            // 打印 token 用于调试
            System.out.println("Token to parse: " + token);

            Claims claims = Jwts.parser()
                    .setSigningKey(secretKey.getBytes()) // 使用原始的秘钥字节数组
                    .setAllowedClockSkewSeconds(72000)
                    .parseClaimsJws(token.replace("Bearer ", "")) // 去除 "Bearer " 前缀再解析
                    .getBody();

            return claims;
        } catch (Exception e) {
            // 打印异常信息用于调试
            e.printStackTrace();
            return null;
        }
    }


    public static Authentication getAuthentication(Map<String, Object> payload2) {
        Employ employ = new Employ();
        employ.setId(Convert.toInt(payload2.get(JwtClaimConstants.EMPLOYEE_ID))); //员工id

        System.out.println("12");

        // 角色集合
        SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN");

//        Set<SimpleGrantedAuthority> authorities = ((JSONArray) payload2.get(JwtClaimConstants.EMPLOYEE_ID))
//                .stream()
//                .map(authority -> new SimpleGrantedAuthority(Convert.toStr(authority)))
//                .collect(Collectors.toSet());

        return new UsernamePasswordAuthenticationToken(employ, "", Collections.singleton(authority));

    }
}
